package net.zoneland.knowledge.service.impl.search;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import net.zoneland.knowledge.config.EsConfig;
import net.zoneland.knowledge.constant.BizConstant;
import net.zoneland.knowledge.constant.Constants;
import net.zoneland.knowledge.constant.FieldConstant;
import net.zoneland.knowledge.constant.SystemConstant;
import net.zoneland.knowledge.enums.DictParentEnum;
import net.zoneland.knowledge.enums.TypeEnum;
import net.zoneland.knowledge.model.DictItem;
import net.zoneland.knowledge.model.EsQuestion;
import net.zoneland.knowledge.model.QaResponse;
import net.zoneland.knowledge.service.DictItemService;
import net.zoneland.knowledge.utils.ElasticSearchPoolUtil;
import net.zoneland.knowledge.utils.EsQueryUtils;
import net.zoneland.knowledge.utils.ResponseUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 违禁词搜索.
 *
 * @author: bcc
 * 2021/5/26
 */
@Service("searchOperationImplQueryStopWords")
public class SearchOperationImplQueryStopWords extends AbstractSearchOperation {

    /**
     * logger.
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(SearchOperationImplQueryStopWords.class);

    /**
     * guava缓存，获取内存
     */
    private static final Cache<String, List<String>> cache = CacheBuilder.newBuilder().expireAfterWrite(30, TimeUnit.MINUTES).build();

    /**
     * 固定词组缓存key.
     */
    private static final String STOP_WORD_KEY = "stopWordKey";

    @Autowired
    private DictItemService dictItemService;

    /**
     * 获取停用词.
     *
     * @return 关键字列表
     */
    private List<String> getStopWordsList() throws ExecutionException {
        List<String> list = cache.get(STOP_WORD_KEY, () -> {
            List<DictItem> dicts = dictItemService.findDictByParentId(DictParentEnum.STOP_TERM.getValue());
            if (CollectionUtils.isNotEmpty(dicts)) {
                return dicts.stream().map(DictItem::getDictName).collect(Collectors.toList());
            }
            //  guava 设置expireAfterWrite后返回null会报错
            return new ArrayList<>();
        });
        return list;
    }

    @Override
    protected void doSearchOrDeal(final SearchDto searchDto) throws Exception {
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("start queryStopWord {}", searchDto);
        }
        String queryText = searchDto.getQaQueryDto().getQueryText();
        if(StringUtils.isEmpty(queryText)) {
            return;
        }
        List<String> stopWordsList = getStopWordsList();
        if(stopWordsList.contains(queryText)) {
            final String noAnswer = dictItemService.findDictByParentId(DictParentEnum.NO_ANSWER_REPLY.getValue()).stream().
                filter(dictItem -> Constants.NO_ANSWER_KEY_ANSWER.equals(dictItem.getDictValue())).map(
                DictItem::getDictName).findFirst().orElse(null);
            QaResponse qaResponse = ResponseUtils.generateNoAnswer(searchDto.getQaQueryDto().getRobotName(), noAnswer);
            searchDto.setQaResponse(qaResponse);
            searchDto.setStopSearch(true);
            searchDto.setStopDeal(true);
        }
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("end queryStopWord {}", searchDto);
        }
    }



}
